package com.love.cloud.auth.service.impl;

import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import com.alibaba.cloud.commons.lang.StringUtils;
import com.love.cloud.auth.service.AuthenticationTokenService;
import com.love.cloud.auth.vo.AuthenticationTokenVo;
import com.love.cloud.common.core.constant.CacheConstants;
import com.love.cloud.common.core.util.RedisUtils;
import com.love.cloud.common.security.service.MyUser;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.exceptions.InvalidTokenException;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @author hongdongqu
 */
@Service
public class AuthenticationTokenServiceImpl implements AuthenticationTokenService {
    @Resource
    public TokenStore tokenStore;
    @Resource
    private RedisUtils redisUtils;

    // 密匙
    private final String privateKey="MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEA0vfvyTdGJkdbHkB8mp0f3FE0GYP3AYPaJF7jUd1M0XxFSE2ceK3k2kw20YvQ09NJKk+OMjWQl9WitG9pB6tSCQIDAQABAkA2SimBrWC2/wvauBuYqjCFwLvYiRYqZKThUS3MZlebXJiLB+Ue/gUifAAKIg1avttUZsHBHrop4qfJCwAI0+YRAiEA+W3NK/RaXtnRqmoUUkb59zsZUBLpvZgQPfj1MhyHDz0CIQDYhsAhPJ3mgS64NbUZmGWuuNKp5coY2GIj/zYDMJp6vQIgUueLFXv/eZ1ekgz2Oi67MNCk5jeTF2BurZqNLR3MSmUCIFT3Q6uHMtsB9Eha4u7hS31tj1UWE+D+ADzp59MGnoftAiBeHT7gDMuqeJHPL4b+kC+gzV4FGTfhR9q3tTbklZkD2A==";
    // 公匙
    private final String publicKey="MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANL378k3RiZHWx5AfJqdH9xRNBmD9wGD2iRe41HdTNF8RUhNnHit5NpMNtGL0NPTSSpPjjI1kJfVorRvaQerUgkCAwEAAQ==";

    @Override
    public Object authenticationToken(AuthenticationTokenVo authenticationTokenVo) {
        //从redis中获取到对应的token信息
        Object data = redisUtils.get(CacheConstants.PROJECT_OAUTH_TOKEN+authenticationTokenVo.getEncryptionToken());
        if(data==null){
            throw new BadCredentialsException("无效验证信息");
        }
        String encryptedToken=data.toString();
        RSA rsa = new RSA(privateKey, null);
        //获取到真实的token信息
        String token = new String(rsa.decrypt(encryptedToken, KeyType.PrivateKey));
        if(StringUtils.isBlank(token)){
            throw new BadCredentialsException("token信息解析失败");
        }
        //删除缓存
        redisUtils.del(CacheConstants.PROJECT_OAUTH_TOKEN+authenticationTokenVo.getEncryptionToken());
        return token;
    }

    @Override
    public Object encryptedToken(HttpServletRequest request) {
        //获取到token的信息
        String tokenInfo = request.getHeader("Authorization");
        String token = tokenInfo.replace("Bearer ","");
        // 公钥加密
        RSA rsa = new RSA(null, publicKey);
        String encryptedToken=rsa.encryptBase64(token,KeyType.PublicKey);
        long date = System.currentTimeMillis();//加入毫秒级的后缀
        String uuid = UUID.randomUUID().toString().replace("-", "")+date;
        //保存到redis中
        if(StringUtils.isNotBlank(encryptedToken)){
            //设置1分钟过期
            redisUtils.set(CacheConstants.PROJECT_OAUTH_TOKEN+uuid,encryptedToken,1, TimeUnit.MINUTES);
        }
        return uuid;
    }

    @Override
    public Object infoByToken(String token) {
        OAuth2AccessToken oAuth2AccessToken = tokenStore.readAccessToken(token);
        if (oAuth2AccessToken == null) {
            throw new InvalidTokenException("请传入正确的token");
        } else if (oAuth2AccessToken.isExpired()) {
            throw new InvalidTokenException("Token已经过期了");
        } else {
            OAuth2Authentication authentication = tokenStore.readAuthentication(oAuth2AccessToken.getValue());
            Object principal = authentication.getPrincipal();
            MyUser myUser=null;
            if (principal instanceof MyUser) {
                myUser=(MyUser) principal;
            }
            if(myUser==null){
                throw new InvalidTokenException("获取到用户信息为空");
            }
            Map<String,Object> map=new HashMap<>();
            map.put("name",myUser.getUserInfo().getSysUser().getName());
            map.put("ZDingAccountId",myUser.getUserInfo().getSysUser().getZDingAccountId());
            map.put("ZDingEmployeeCode",myUser.getUserInfo().getSysUser().getZDingEmployeeCode());
            map.put("mobile",myUser.getUserInfo().getSysUser().getMobile());
            return map;
        }
    }

}
